import { Player, Position, GameState, BOARD_SIZE, DIRECTIONS } from '../types/game';

// 创建空棋盘
export const createEmptyBoard = (): Player[][] => {
  return Array(BOARD_SIZE).fill(null).map(() => Array(BOARD_SIZE).fill(null));
};

// 初始化游戏状态
export const initializeGame = (gameMode: 'pvp' | 'ai'): GameState => ({
  board: createEmptyBoard(),
  currentPlayer: 'black', // 黑棋先手
  gameMode,
  gameStatus: 'playing',
  winner: null,
  moveCount: 0,
  lastMove: null,
  winningLine: [],
});

// 检查位置是否有效
export const isValidPosition = (row: number, col: number): boolean => {
  return row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE;
};

// 检查位置是否为空
export const isEmpty = (board: Player[][], row: number, col: number): boolean => {
  return isValidPosition(row, col) && board[row][col] === null;
};

// 放置棋子
export const placePiece = (board: Player[][], row: number, col: number, player: Player): Player[][] => {
  if (!isEmpty(board, row, col)) {
    throw new Error('Position is not empty');
  }
  
  const newBoard = board.map(r => [...r]);
  newBoard[row][col] = player;
  return newBoard;
};

// 检查五子连珠
export const checkWin = (board: Player[][], row: number, col: number, player: Player): Position[] => {
  for (const { dr, dc } of DIRECTIONS) {
    const line: Position[] = [{ row, col }];
    
    // 正方向检查
    for (let i = 1; i < 5; i++) {
      const newRow = row + dr * i;
      const newCol = col + dc * i;
      if (isValidPosition(newRow, newCol) && board[newRow][newCol] === player) {
        line.push({ row: newRow, col: newCol });
      } else {
        break;
      }
    }
    
    // 反方向检查
    for (let i = 1; i < 5; i++) {
      const newRow = row - dr * i;
      const newCol = col - dc * i;
      if (isValidPosition(newRow, newCol) && board[newRow][newCol] === player) {
        line.unshift({ row: newRow, col: newCol });
      } else {
        break;
      }
    }
    
    if (line.length >= 5) {
      return line.slice(0, 5); // 返回连续的5子
    }
  }
  
  return [];
};

// 检查游戏是否结束
export const checkGameEnd = (board: Player[][], lastMove: Position | null): { winner: Player; winningLine: Position[] } => {
  if (!lastMove) {
    return { winner: null, winningLine: [] };
  }
  
  const { row, col } = lastMove;
  const player = board[row][col];
  
  if (!player) {
    return { winner: null, winningLine: [] };
  }
  
  const winningLine = checkWin(board, row, col, player);
  
  if (winningLine.length > 0) {
    return { winner: player, winningLine };
  }
  
  return { winner: null, winningLine: [] };
};

// 获取所有可能的移动位置
export const getValidMoves = (board: Player[][]): Position[] => {
  const moves: Position[] = [];
  
  for (let row = 0; row < BOARD_SIZE; row++) {
    for (let col = 0; col < BOARD_SIZE; col++) {
      if (board[row][col] === null) {
        moves.push({ row, col });
      }
    }
  }
  
  return moves;
};

// 评估棋盘局面（用于AI）
export const evaluateBoard = (board: Player[][], player: Player): number => {
  let score = 0;
  const opponent = player === 'black' ? 'white' : 'black';
  
  for (let row = 0; row < BOARD_SIZE; row++) {
    for (let col = 0; col < BOARD_SIZE; col++) {
      if (board[row][col] === player) {
        score += evaluatePosition(board, row, col, player);
      } else if (board[row][col] === opponent) {
        score -= evaluatePosition(board, row, col, opponent);
      }
    }
  }
  
  return score;
};

// 评估单个位置的分数
const evaluatePosition = (board: Player[][], row: number, col: number, player: Player): number => {
  let score = 0;
  
  for (const { dr, dc } of DIRECTIONS) {
    const line = getLine(board, row, col, dr, dc, player);
    score += getLineScore(line.length, player);
  }
  
  return score;
};

// 获取指定方向的连线
const getLine = (board: Player[][], row: number, col: number, dr: number, dc: number, player: Player): Player[] => {
  const line: Player[] = [];
  
  // 向两个方向扩展
  for (let i = -4; i <= 4; i++) {
    const newRow = row + dr * i;
    const newCol = col + dc * i;
    
    if (isValidPosition(newRow, newCol)) {
      line.push(board[newRow][newCol]);
    } else {
      line.push(null);
    }
  }
  
  return line;
};

// 根据连线长度计算分数
const getLineScore = (length: number, player: Player): number => {
  const scores = {
    1: 1,
    2: 10,
    3: 100,
    4: 1000,
    5: 10000,
  };
  
  return scores[length as keyof typeof scores] || 0;
};

// Minimax算法实现
export const minimax = (
  board: Player[][],
  depth: number,
  isMaximizing: boolean,
  alpha: number,
  beta: number,
  aiPlayer: Player
): { score: number; position?: Position } => {
  const { winner } = checkGameEnd(board, null);
  
  // 终止条件
  if (depth === 0 || winner) {
    if (winner === aiPlayer) return { score: 10000 };
    if (winner && winner !== aiPlayer) return { score: -10000 };
    return { score: evaluateBoard(board, aiPlayer) };
  }
  
  const validMoves = getValidMoves(board);
  
  if (isMaximizing) {
    let maxScore = -Infinity;
    let bestPosition: Position | undefined;
    
    for (const move of validMoves) {
      const newBoard = placePiece(board, move.row, move.col, aiPlayer);
      const result = minimax(newBoard, depth - 1, false, alpha, beta, aiPlayer);
      
      if (result.score > maxScore) {
        maxScore = result.score;
        bestPosition = move;
      }
      
      alpha = Math.max(alpha, result.score);
      if (beta <= alpha) break; // Alpha-beta剪枝
    }
    
    return { score: maxScore, position: bestPosition };
  } else {
    let minScore = Infinity;
    let bestPosition: Position | undefined;
    const opponent = aiPlayer === 'black' ? 'white' : 'black';
    
    for (const move of validMoves) {
      const newBoard = placePiece(board, move.row, move.col, opponent);
      const result = minimax(newBoard, depth - 1, true, alpha, beta, aiPlayer);
      
      if (result.score < minScore) {
        minScore = result.score;
        bestPosition = move;
      }
      
      beta = Math.min(beta, result.score);
      if (beta <= alpha) break; // Alpha-beta剪枝
    }
    
    return { score: minScore, position: bestPosition };
  }
};

// AI获取最佳移动
export const getAIMove = (board: Player[][], aiPlayer: Player, difficulty: number = 3): Position | null => {
  const validMoves = getValidMoves(board);
  
  if (validMoves.length === 0) return null;
  
  // 如果是第一步，选择中心位置
  if (validMoves.length === BOARD_SIZE * BOARD_SIZE) {
    return { row: Math.floor(BOARD_SIZE / 2), col: Math.floor(BOARD_SIZE / 2) };
  }
  
  // 使用Minimax算法
  const result = minimax(board, difficulty, true, -Infinity, Infinity, aiPlayer);
  
  return result.position || validMoves[0];
};

// 切换玩家
export const switchPlayer = (currentPlayer: Player): Player => {
  return currentPlayer === 'black' ? 'white' : 'black';
};